#include <stdlib.h>
#include <gl/glut.h>
#include <gl/glui.h>
#include <gl/gl.h>
#include <iostream>
#include <fstream>
#include "Figure.h"
#include "Grid.h"
#include "Trajectory.h"
#include "extrusion.h"




using namespace std;
//gui
float view_rotate[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
float obj_trans[] = { 0.0, 0.0, 0.0 };
float sca_x,sca_y,sca_z=0.0;
GLUI *glui;
GLUI_RadioGroup *radio;
GLUI_EditText   *filetext, *wXtext, *wYtext,wZtext;

std::string stringfile = "";
std::string stringXw = "";
std::string stringYw = "";
std::string stringZw = "";

bool iniciado=false;

float mouse_x, mouse_y;
float rotation_x=0.0;
float rotation_y=0.0;
float profundidad=0.0;
bool BotonIzquierda=false;
bool BotonDerecha=false;



bool flagerror=false;

char  filename[128];

int   WindowSizeH = 450;
int   WindowSizeW = 300;

int trajWidth=100;//datos que introducira el usuario
int figuWidth=100;

int TamRealVentanaH=450;
int TamRealVentanaW=300;

bool bTrajectory=true;

float RedGrid=240;
float GreenGrid=128;
float BlueGrid=128;


float RedShape=0;
float GreenShape=0;
float BlueShape=0;

float RedBackground=255;
float GreenBackground=255;
float BlueBackground=255;

float RedTraj=0;
float GreenTraj=0;
float BlueTraj=0;

//cosas generales
Figure  figure;
Grid grid;
Trajectory trayectoria;
extrusion extru;


//declaraciones generales

//subventanas defincion y funciones

int ventIzq;
void IzqDisplay();
void IzqReshape(int w, int h);

int ventDer;
void DerDisplay();
void DerReshape(int w, int h);

int ventCentral;
void CentralDisplay();
void CentralReshape(int w, int h);

int ventPrincipal;
void PrincipalReshape(int w, int h);
void PrincipalDisplay();
//

void ModoTrabajo();
void drawString(char* s);
void TrayectoriaEjes();
void FiguraEjes();
void ExtrusionEjes();
static char label[100];



//void sub_sub_colors(int value);

void setCamera(float posX, float posY, float posZ, float targetX, float targetY, float targetZ);



void saveFigure(const char *fname)
{
	std::ofstream file(fname);
	file<<trajWidth<<endl;
	trayectoria.save(file);

	file<<figuWidth<< std::endl;
	figure.save(file);

	file.close();
}

//modificar para que cargue los datos como deberia etc
void loadFigure(const char *fname )
{
	// Trying to load the file
	std::ifstream file(fname);
	if (file.is_open())
	{	
		trajWidth=trayectoria.load(file);
		figuWidth=figure.load( file);
		extru.load(&figure,&trayectoria);
		file.close();
	}
	


	sca_x=1;
	sca_y=1;
	sca_z=1;
}	

//funcion en subventanas.cpp para escribir a pantalla
void drawString (char *s)
{
  unsigned int i;
  for (i = 0; i < strlen (s); i++)
    glutBitmapCharacter (GLUT_BITMAP_HELVETICA_12, s[i]);
};

void drawStringMini (char *s)
{
  unsigned int i;
  for (i = 0; i < strlen (s); i++)
    glutBitmapCharacter (GLUT_BITMAP_HELVETICA_10, s[i]);
};

void myGlutMotion(int x, int y )
{
	if(BotonIzquierda)
	{rotation_x +=  (y - mouse_y);
	rotation_y +=  (x - mouse_x);}
	else if(BotonDerecha)
	{
		profundidad+=(y-mouse_y);
	}

	mouse_x = x;
	mouse_y = y;

	glutPostRedisplay(); 
}
void click(int button, int state, int x, int y)
{

if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
		mouse_x = x;
		mouse_y = y;
		BotonIzquierda=true;
		BotonDerecha=false;
	}
else if( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN ) {
		mouse_y = y;
		BotonIzquierda=false;
		BotonDerecha=true;
		
	}

}




void keyboard (unsigned char tecla, int x, int y)
{
	switch (tecla)
	{
	case 27: // Escape
		saveFigure(filename);
		break;
	}
}


int init (void) 
{


	glClearColor (0.0, 0.0, 0.0, 0.0);
	

	glutMouseFunc (click);
	glutMotionFunc( myGlutMotion );
	glutKeyboardFunc(keyboard);




	return 0;
}

void ModoTrabajo()
{
	glutSetWindow(ventDer);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	gluOrtho2D (-figuWidth/2, figuWidth/2, -figuWidth/2, figuWidth/2);
	glutPostRedisplay();

	glutSetWindow(ventIzq);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	gluOrtho2D (-trajWidth/2, trajWidth/2, 0, trajWidth);
	glutPostRedisplay();

	glutSetWindow(ventCentral);
	glutPostRedisplay();


}

void control_cb( int control )
{
	char temp[128];

	switch(control){

		case 1:
				loadFigure(filename);
	
	figure.deleteRewrite();

	trayectoria.deleteRewrite();
	ModoTrabajo();
	iniciado=true;
			break;

		case 2:
			strcpy(filename, stringfile.c_str());
			
			break;

		case 3:

		
			break;

		case 4:

		
			break;

		case 5:
			
			break;

		default:
			break;
	}

	ModoTrabajo();
	CentralDisplay();
	IzqDisplay();
	DerDisplay();

}


int main(int argc, char** argv)
{

	// Initialize GLUT
	glutInit(&argc, argv);

	// Request a double buffer
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);


	// Window size (width, height)
	//glutInitWindowSize (WindowSizeW, WindowSizeH); 

	// Initial position (x, y) 
	glutInitWindowPosition (50, 50);

	//Real Size of the window
	glutInitWindowSize(TamRealVentanaW,TamRealVentanaH);
	

	setCamera(0, 0, 550, 0, 0, 0);

	// Set the display callback
	//glutDisplayFunc(display); 
	

	ventPrincipal=glutCreateWindow("Assignment1 - IGU");
	glutDisplayFunc(PrincipalDisplay);
	glutReshapeFunc(PrincipalReshape);

	ventIzq=glutCreateSubWindow(ventPrincipal,0,(WindowSizeH/3)*2,WindowSizeW/2,WindowSizeH/3);
	glutDisplayFunc(IzqDisplay);
	glutReshapeFunc(IzqReshape);

	ventDer=glutCreateSubWindow(ventPrincipal,WindowSizeW/2,(WindowSizeH/3)*2,WindowSizeW/2,WindowSizeH/3);
	glutDisplayFunc(DerDisplay);
	glutReshapeFunc(DerReshape);

	ventCentral=glutCreateSubWindow(ventPrincipal,0,0,WindowSizeW,(WindowSizeH/3)*2);
	glutDisplayFunc(CentralDisplay);
	glutReshapeFunc(CentralReshape);



	// Initialize the application and OpenGL
	init ();

	
	
	//GLUI


	int var;
	glui = GLUI_Master.create_glui( "Figure Mods",0,400,50 );
	



	filetext = new GLUI_EditText( glui, "Filename:", stringfile, 2, control_cb );
	new GLUI_Button( glui, "Load", 1, control_cb);

	new GLUI_EditText( glui, "Scale X:", &sca_x, 3, control_cb );
	 new GLUI_EditText( glui, "Scale Y:", &sca_y, 4, control_cb );
	 new GLUI_EditText( glui, "Scale Z:", &sca_z, 5, control_cb );

	 new GLUI_Translation(glui,"Translate X",GLUI_TRANSLATION_X,&obj_trans[0],6,control_cb);
	  new GLUI_Translation(glui,"Translate Y",GLUI_TRANSLATION_Y,&obj_trans[1],7,control_cb);
	new GLUI_Translation(glui,"Translate Z",GLUI_TRANSLATION_Z,&obj_trans[2],8,control_cb);



	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// Main loop
	if(!iniciado)
	{
	FiguraEjes();
	grid.renderFigura(figuWidth);
	TrayectoriaEjes();
	grid.renderTrayectoria(trajWidth);
	}
	glutMainLoop();

	return 0;
}

void BordeDerecha()
{
	glColor3f(0.6,0.6,0.6);
	glLineWidth(3.0f);
	glBegin(GL_LINES);
	glVertex2f(trajWidth/2,trajWidth);
	glVertex2f(trajWidth/2,0);
	glEnd();

	//borde arriba
	glColor3f(0.6,0.6,0.6);
	glLineWidth(6.0f);
	glBegin(GL_LINES);
	glVertex2f(-trajWidth/2,trajWidth);
	glVertex2f(trajWidth/2,trajWidth);
	glEnd();

	
}
void IzqDisplay()
{
	 /* Borra la subventana */
    glutSetWindow (ventIzq);
	glClearColor(RedBackground,GreenBackground,BlueBackground,0.0);//cambiar a los background cuando tenga un sistema;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  

	BordeDerecha();

		TrayectoriaEjes();
		grid.renderTrayectoria(trajWidth);
		//TrayectoriaEjes();
		trayectoria.renderTrajectory();
		

		//ModoTrabajo();

	glFlush();
	glutSwapBuffers();

}

void IzqReshape(int w, int h)
{

		glViewport(0,0,w,h);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluOrtho2D(-trajWidth/2,trajWidth/2,0,trajWidth);
	
}
void BordeIzquierda()
{
	glColor3f(0.6,0.6,0.6);
	glLineWidth(3.0f);
	glBegin(GL_LINES);
	glVertex2f(-figuWidth/2,figuWidth/2);
	glVertex2f(-figuWidth/2,-figuWidth/2);
	glEnd();

	//borde arriba

glColor3f(0.6,0.6,0.6);
	glLineWidth(6.0f);
	glBegin(GL_LINES);
	glVertex2f(-figuWidth/2,figuWidth/2);
	glVertex2f(figuWidth/2,figuWidth/2);
	glEnd();

	
}

void DerDisplay()
{
	glutSetWindow(ventDer);
	glClearColor(RedBackground,GreenBackground,BlueBackground,0.0);//cambiar a los background cuando tenga un sistema;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	
		
	BordeIzquierda();
	FiguraEjes();
	grid.renderFigura(figuWidth);
	
		
	figure.renderFigure(iniciado);
		
	//ModoTrabajo();

	glFlush();
	glutSwapBuffers();


}
void DerReshape(int w, int h)
{
	
		glViewport(0,0,w,h);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluOrtho2D(-figuWidth/2,figuWidth/2,-figuWidth/2,figuWidth/2);
	

	

}

void CentralDisplay()
{

	glutSetWindow(ventCentral);
	glClearColor(1, 0.7, 1,0.0);//cambiar a los background cuando tenga un sistema;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	gluPerspective(60.0, 1.0, 0.1, 200.0);
	glMatrixMode( GL_MODELVIEW );

	setCamera(0,0,figuWidth,0,0,0); 

	glTranslatef(0,0,profundidad);
	glRotatef( rotation_y, 0.0, 0.5, 0.0 );
	glRotatef( rotation_x, 0.5, 0.0, 0.0 );
	



	//extru.renderextrusion();
	ExtrusionEjes();

	
	glPushMatrix();
	glTranslatef(obj_trans[0],obj_trans[1],obj_trans[2]);
	glScalef(sca_x,sca_y,sca_z);

	extru.renderextrusion(); 
	
	glPopMatrix();

	glFlush;

	

	glutSwapBuffers();

}
void CentralReshape(int w, int h)
{
		
}

void PrincipalReshape(int w, int h)
{
	
	glViewport(0,0,WindowSizeW,WindowSizeH);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-1.0,1.0,-1.0,1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glutSetWindow(ventDer);
	glutReshapeWindow(WindowSizeW/2,(WindowSizeH)/3);
	glutPositionWindow(WindowSizeW/2,((WindowSizeH)/3)*2);

	glutSetWindow(ventIzq);
	glutReshapeWindow(WindowSizeW/2,(WindowSizeH)/3);
	glutPositionWindow(0,((WindowSizeH)/3)*2);

	glutSetWindow(ventCentral);
	glutReshapeWindow(WindowSizeW,WindowSizeH-((WindowSizeH)/3));
	glutPositionWindow(0,0);

	glutSetWindow(ventPrincipal);
	glutReshapeWindow(TamRealVentanaW,TamRealVentanaH);

}

void PrincipalDisplay()
{
	glutSetWindow(ventPrincipal);
	glClearColor(1.0,0.0,0.5,0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glFlush();
	glutSwapBuffers();
	

}

void TrayectoriaEjes()
{
	

	glColor3f(0.9f, 0, 0);
	glLineWidth(5.0f);
	glBegin(GL_LINES);
	glVertex2f(-trajWidth/2+trajWidth/5, 0);
	glVertex2f(trajWidth/2-trajWidth/5, 0);
	glEnd();

	glColor3f(0,0.9f, 0 );
	glLineWidth(3.0f);
	glBegin(GL_LINES);	
	glVertex2f(0,0);
	glVertex2f(0,trajWidth-trajWidth/8);
	glEnd();

	glLineWidth(1.0f);	
}
void FiguraEjes()
{

	glColor3f(0.9f, 0, 0);
	glLineWidth(3.0f);
	glBegin(GL_LINES);
	glVertex3f(-figuWidth/2+figuWidth/10, 0,0);
	glVertex3f(figuWidth/2-figuWidth/10, 0,0);
	glEnd();

	glColor3f(0, 0, 0.9f);

	glBegin(GL_LINES);	
	glVertex3f(0,-figuWidth/2+figuWidth/10,0);
	glVertex3f(0,figuWidth/2-figuWidth/10,0);
	glEnd();


	glLineWidth(1.0f);	
}

void ExtrusionEjes()
{

	glColor3f(0.9f, 0, 0);
	glLineWidth(3.0f);
	glBegin(GL_LINES);
	glVertex3f(-figuWidth/2, 0,0);
	glVertex3f(figuWidth/2, 0,0);
	glEnd();

	glColor3f(0, 0.9, 0);

	glBegin(GL_LINES);	
	glVertex3f(0,-figuWidth/2,0);
	glVertex3f(0,figuWidth/2,0);
	glEnd();

	glColor3f(0,0,0.9);

	glBegin(GL_LINES);	
	glVertex3f(0,0,-figuWidth/2);
	glVertex3f(0,0,figuWidth/2);
	glEnd();

glLineWidth(1.0f);
	

}


void setCamera(float posX, float posY, float posZ, float targetX, float targetY, float targetZ)
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(posX, posY, posZ, targetX, targetY, targetZ, 0, 1, 0); // eye(x,y,z), focal(x,y,z), up(x,y,z)
}





